/* linkit.js
 * By François Leporcq
 * MIT Licensed.
 */
var RaphaelWorkspace = AbstractWorkspace.extend({
    _className: "RaphaelWorkspace",
    init: function(container){
        this._container = container;
        this._shapes = new Array();
        this._dragger = new Dragger(this);
        var self = this;
        this._container.canvas.onmousemove = function(event){
            self._dragger.move(event);
            self._container.onselectstart = function(){ return false; };
        };
        this._container.canvas.onmouseup= function(){
            self._dragger.deselect()
            self._container.onselectstart = function(){ return true; };
        };
    },
    //@Override
    clearAll: function(){
        this._container.clear();
    },
    //@Override
    clear: function(shape){
        if(shape && shape.element && shape.element.node){
            this.getContainer().canvas.removeChild(shape.element.node);
        }
    },
    _makeDraggable: function(shape){
        var self = this;
        shape.element.mousedown(function(event){self._dragger.select(event, shape)});
    },
    _addCssClasses: function(shape, cssClasses){

        if(!cssClasses || cssClasses.length == 0){
            return;
        }

        if(shape instanceof Composite){
            var subShapes = shape.getShapes();
            for(var i=0 ; i < subShapes.length ; i++){
                var cssClassesClone = ObjectUtils.clone(cssClasses);
                this._applyCssClasses(subShapes[i],cssClassesClone);
            }

        }else if(shape.element.node){
            shape.element.node.setAttribute("class", cssClasses.join(" "));
        }

    },
    //@Override
    draw : function(shape){
        if(shape == null){
            return;
        }

        if(!(shape instanceof AbstractShape)){
            throw new Error("The object to draw must be a child class of AbstractShape");
        }else if(shape instanceof Point){
            this._drawPoint(shape);
        }else if(shape instanceof Line){
            this._drawLine(shape);
        }else if(shape instanceof Polygon || shape instanceof Polyline){
            this._drawPolygon(shape);
        }else if(shape instanceof AbstractImage){
            this._drawImage(shape);
        }else if(shape instanceof Text){
            this._drawText(shape);
        }else if(shape instanceof Rectangle){
            this._drawRectangle(shape);
        }else if(shape instanceof Circle){
            this._drawCircle(shape);
        }else if(shape instanceof Ellipse){
            this._drawEllipse(shape);
        }else if(shape instanceof BezierCurve){
            this._drawBezierCurve(shape);
        }else if(shape instanceof Composite){
            this._drawComposite(shape);
        }

        this._applyCssClasses(shape);

        if(!shape.isPartOfComposite() && shape.implementationOf(Linkable)){
            this._makeDraggable(shape);
        }
    },
    _drawPoint: function(point){
        if(!point.element){
            point.element = this._container.circle(null,null,3);
        }
        var origin = point.getOrigin();
        point.element.attr({
            "cx": origin.getX(),
            "cy": origin.getY()
        });
    },
    _drawCircle: function(circle){
        if(!circle.element){
            circle.element = this._container.circle(null,null,circle.getRadius());
        }
        var origin = circle.getOrigin();
        circle.element.attr({
            "cx": origin.getX(),
            "cy": origin.getY()
        });
    },
    _drawEllipse: function(ellipse){
        if(!ellipse.element){
            ellipse.element = this._container.ellipse(null, null, ellipse.getXRadius(), ellipse.getYRadius());
        }
        var origin = ellipse.getOrigin();
        ellipse.element.attr({
            "cx": origin.getX(),
            "cy": origin.getY()
        });
    },
    _drawRectangle: function(rectangle){
        if(!rectangle.element){
            rectangle.element = this._container.rect(null, null, rectangle.getWidth(), rectangle.getHeight());
        }
        var origin = rectangle.getOrigin();
        rectangle.element.attr({
            "x": origin.getX(),
            "y": origin.getY()
        });


    },
    _drawImage: function(image){
        if(!image.element){
            image.element = this._container.image(image.getSrc(), null, null,image.getWidth(), image.getHeight());
        }
        var origin = image.getOrigin();
        image.element.attr({
            "x": origin.getX(),
            "y": origin.getY()
        });
    },
    _drawLine: function(line){
        if(!line.element){
            line.element = this._container.path();
        }
        line.element.attr({
            "path": "M" + line.getStart().getX() + "," + line.getStart().getY() + "L" + line.getEnd().getX() + "," + line.getEnd().getY()
        });
    },
    _drawPolygon: function(polygon){
        if(!polygon.element){
            polygon.element = this._container.path();
        }
        var pointsStringBuilder = new Array();
        for(var i = 0 ; i < polygon.getPoints().length ; i++){
            pointsStringBuilder.push(polygon.getPoints()[i].getX()+","+polygon.getPoints()[i].getY());
        }
        var pointsString = pointsStringBuilder.join(" L ");

        polygon.element.attr({
            "path": "M " + pointsString + (polygon instanceof Polyline ? "" :" Z")
        });

    },
    _drawText: function(text){
        if(!text.element){
            text.element = this._container.text(null,null,text.getContent());
            text.element.attr({
                "font-size": Workspace.text.fontSize,
                "font-family": Workspace.text.fontFamily,
                "text-anchor": Workspace.text.anchor
            });
        }
        var origin = text.getOrigin();

        //TODO: Cause un gros ralentissement lors du drag avec firefox
        text.element.attr({
            "x": origin.getX(),
            "y": origin.getY()
        });
//        text.element.node.setAttribute("x", origin.getX());
//        text.element.node.setAttribute("y", origin.getY());
    },
    _drawBezierCurve: function(curve){
        if(!curve.element){
            curve.element = this._container.path();
        }
        if(curve.getSecondControl() == null){
            var path = "M " + curve.getStart().getX() + " " + curve.getStart().getY() + " Q " + curve.getFirstControl().getX() + " " + curve.getFirstControl().getY() + " " + curve.getEnd().getX() + " " + curve.getEnd().getY()
        }else{
            var path = "M  " + curve.getStart().getX() + " " + curve.getStart().getY() + " C " + curve.getFirstControl().getX() + " " + curve.getFirstControl().getY() + " " + curve.getSecondControl().getX() + " " + curve.getSecondControl().getY()+" "+curve.getEnd().getX() + " " + curve.getEnd().getY();
        }
        curve.element.attr({
            "path": path
        });


    },
    _drawComposite: function(composite){

        composite.element = this._container.set();

        var shapes = composite.getShapes();
        for(var i = 0 ; i < shapes.length ; i++){
            this.draw(shapes[i]);
            composite.element.push(shapes[i].element)
        }
    }

});
